package ffte.test.types

import spinal.core._
import spinal.core.sim._
import ffte.types._

/**
 * 简化的类型转换测试
 * 修复了位宽溢出问题
 */
class TypeConversionSimpleTest extends Component {
  val io = new Bundle {
    val fixreal_input = in SInt(16 bits)
    val fixcomplex_real = out SInt(16 bits)
    val fixcomplex_imag = out SInt(16 bits)
  }

  val conversionArea = new Area {
    // FixReal到FixComplex的转换
    val fixReal = FixReal(16, -8)
    fixReal.d.raw := io.fixreal_input
    
    // 创建FixComplex并赋值
    val fixComplex = FixComplex(16, -8)
    fixComplex.re.d.raw := fixReal.d.raw  // 实部来自FixReal
    fixComplex.im.d.raw := S(0)           // 虚部为零
    
    io.fixcomplex_real := fixComplex.re.d.raw
    io.fixcomplex_imag := fixComplex.im.d.raw
  }
}

/**
 * VecComplex基本测试 - 简化版本
 */
class VecComplexSimpleTest extends Component {
  val io = new Bundle {
    val real_input = in Vec(SInt(16 bits), 2)
    val imag_input = in Vec(SInt(16 bits), 2)
    val real_output = out Vec(SInt(16 bits), 2)
    val imag_output = out Vec(SInt(16 bits), 2)
  }

  val vecArea = new Area {
    // 创建2元素的VecComplex
    val vecComplex = VecComplex(2, 16, -8)
    
    // 填充VecComplex
    for (i <- 0 until 2) {
      vecComplex.d(i).re.d.raw := io.real_input(i)
      vecComplex.d(i).im.d.raw := io.imag_input(i)
    }
    
    // 输出 - 只是简单地回传
    for (i <- 0 until 2) {
      io.real_output(i) := vecComplex.d(i).re.d.raw
      io.imag_output(i) := vecComplex.d(i).im.d.raw
    }
  }
}

/**
 * 完整类型转换测试仿真
 */
object TypeConversionSimpleTestSim {
  def main(args: Array[String]): Unit = {
    // 测试1：FixReal到FixComplex的转换
    println("开始FixReal到FixComplex转换测试...")
    SimConfig.withWave.compile(new TypeConversionSimpleTest()).doSim { dut =>
      dut.clockDomain.forkStimulus(period = 10)
      
      // 测试不同的输入值
      val test_values = Array(0.0, 1.0, -1.0, 2.5, -3.7)
      
      for (value <- test_values) {
        dut.io.fixreal_input #= Math.round(value * 128)
        dut.clockDomain.waitSampling(1)
        
        val real_out = dut.io.fixcomplex_real.toInt
        val imag_out = dut.io.fixcomplex_imag.toInt
        
        println(f"输入: $value (${Math.round(value * 128)}), 输出: ($real_out/128 + ${imag_out}/128i)")
      }
    }
    
    // 测试2：VecComplex基本测试
    println("\n开始VecComplex基本测试...")
    SimConfig.withWave.compile(new VecComplexSimpleTest()).doSim { dut =>
      dut.clockDomain.forkStimulus(period = 10)
      
      // 测试数据：[1+2i, 3-4i]
      dut.io.real_input(0) #= Math.round(1.0 * 128)
      dut.io.imag_input(0) #= Math.round(2.0 * 128)
      dut.io.real_input(1) #= Math.round(3.0 * 128)
      dut.io.imag_input(1) #= Math.round(-4.0 * 128)
      
      dut.clockDomain.waitSampling(1)
      
      val real0 = dut.io.real_output(0).toInt
      val imag0 = dut.io.imag_output(0).toInt
      val real1 = dut.io.real_output(1).toInt
      val imag1 = dut.io.imag_output(1).toInt
      
      println(f"VecComplex测试结果:")
      println(f"  元素0: ($real0/128 + ${imag0}/128i) [期望: (1+2i)]")
      println(f"  元素1: ($real1/128 + ${imag1}/128i) [期望: (3-4i)]")
    }
    
    println("\n类型转换测试完成！")
    println("关键发现：")
    println("1. FixReal可以很容易地转换为FixComplex，虚部设为零")
    println("2. VecComplex提供了处理复数向量的有效方式")
    println("3. 类型转换在硬件层面是直接的信号连接")
    println("4. 位宽匹配在类型转换中很重要")
  }
}